package edu.npu.GraphUtility;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Mapper.Context;
import edu.npu.GraphTransform.GraphMetisQualify.COUNTER;

public class GraphUtility {
	final static String SEPARATOR = "\t";

	// 给文件中的数据唯一的数字标号
	public static void GiveSig(String srcPath, String disPath)
			throws IOException {
		long count = 1;
		final int SIZE = 5 * 1024 * 1024;
		File srcFile = new File(srcPath);
		File[] fList = srcFile.listFiles();
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream(disPath));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(bos),
				SIZE);
		for (File f : fList) {
			if (f.isDirectory())
				continue;
			// 如果文件带有后缀名则不是需要的数据文件
			if (f.toString().split(".").length > 1)
				continue;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(f));
			BufferedReader br = new BufferedReader(new InputStreamReader(bis),
					SIZE);
			String line = null;
			while ((line = br.readLine()) != null) {
				bw.write("#" + count++ + SEPARATOR + line + "\n");
			}
			br.close();
		}
		bw.close();
	}

	// 给数据加上特殊标号
	public static void GiveSig(String srcPath, String disPath, String sig)
			throws IOException {
		final int SIZE = 5 * 1024 * 1024;
		File srcFile = new File(srcPath);
		File[] fList = srcFile.listFiles();
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream(disPath));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(bos),
				SIZE);
		for (File f : fList) {
			if (f.isDirectory())
				continue;
			// 如果文件带有后缀名则不是需要的数据文件
			if (f.toString().split(".").length > 1)
				continue;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(srcFile));
			BufferedReader br = new BufferedReader(new InputStreamReader(bis),
					SIZE);
			String line = null;
			while ((line = br.readLine()) != null) {
				bw.write(sig + line + "\n");
			}
			br.close();
		}
		bw.close();
	}

	public static void RemoveSig(String srcPath, String disPath)
			throws IOException {
		final int SIZE = 5 * 1024 * 1024;
		File srcFile = new File(srcPath);
		File[] fList = srcFile.listFiles();
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream(disPath));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(bos),
				SIZE);
		for (File f : fList) {
			if (f.isDirectory())
				continue;
			// 如果文件带有后缀名则不是需要的数据文件
			if (f.toString().split(".").length > 1)
				continue;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(srcFile));
			BufferedReader br = new BufferedReader(new InputStreamReader(bis),
					SIZE);
			String line = null;
			while ((line = br.readLine()) != null) {
				bw.write(line.substring(line.indexOf(" ") + 1) + "\n");
			}
			br.close();
		}
		bw.close();
	}

	// 将几个文件合并为一个
	public static void Merge(String srcPath, String disPath) throws IOException {
		int current = 0;
		byte[] buf = new byte[1024];
		File source = new File(srcPath);
		File target = new File(disPath);
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream(target));
		for (File file : source.listFiles()) {
			if (file.isDirectory())
				continue;
			if (file.toString().endsWith(".crc")
					|| file.toString().indexOf("part") == -1)
				continue;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(file));
			while ((current = bis.read(buf, 0, 1024)) != -1) {
				bos.write(buf, 0, current);
				bos.flush();
			}
			bis.close();
		}
		bos.close();
	}

	// 将几个文件合并，并在开始添加内容，并去除标号
	public static void Merge(String srcPath, String disPath, String content)
			throws IOException {
		int SIZE = 5 * 1024 * 1024;
		File source = new File(srcPath);
		File target = new File(disPath);
		BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream(target));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(bos));
		bw.write(content);
		for (File file : source.listFiles()) {
			if (file.isDirectory())
				continue;
			if (file.toString().endsWith(".crc")
					|| file.toString().indexOf("part") == -1)
				continue;
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(file));
			BufferedReader br = new BufferedReader(new InputStreamReader(bis),
					SIZE);
			String line = null;
			while ((line = br.readLine()) != null)
				bw.write(line.substring(line.indexOf(SEPARATOR) + 1) + "\n");
			br.close();
		}
		bw.close();
	}

	// 向HDFS中写入文件
	public static void WriteToHDFS(String srcPath, String disPath,
			String content) throws IOException {
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(conf);
		PrintWriter pw = new PrintWriter(fs.append(new Path(disPath)));
		if (!fs.exists(new Path(disPath)))
			fs.createNewFile(new Path(disPath));
		pw.print(content);
		pw.flush();
		pw.close();
	}

	// 运行命令
	public static void Exec(String command) throws IOException {
		// gpmetis命令：gpmetis srcPath num
		String[] commands = { "/bin/bash", "-c", command };
		System.out.println("\"" + command + "\" is executing...");
		Process process = Runtime.getRuntime().exec(commands);
		// 输出错误信息
		BufferedReader err = new BufferedReader(new InputStreamReader(
				process.getErrorStream()));
		// 输出Metis运行信息
		BufferedReader output = new BufferedReader(new InputStreamReader(
				process.getInputStream()));
		String line = null;
		while ((line = err.readLine()) != null) {
			System.out.println(line);
		}
		while ((line = output.readLine()) != null) {
			System.out.println(line);
		}
		err.close();
		output.close();
	}

	// 读入内存的Hash初始化
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static HashMap<Long, Long> HashInitialize(String srcPath,
			Context context) throws IOException {
		HashMap<Long, Long> hashMap = new HashMap<Long, Long>(50000, 1000);
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(conf);
		BufferedReader br = new BufferedReader(new InputStreamReader(
				fs.open(new Path(srcPath))));
		String str = null;
		while ((str = br.readLine()) != null) {
			String[] sp = str.split(SEPARATOR);
			hashMap.put(Long.parseLong(sp[1]), Long.parseLong(sp[0]));
			if (context != null)
				context.getCounter(COUNTER.NODE).increment(1);
		}
		return hashMap;
	}

	// 统计节点和边
	public static void Count(String srcPath) throws FileNotFoundException {
		Scanner scanner = new Scanner(new File(srcPath));
		int[] count = new int[5];
		String str = null;
		while (scanner.hasNext()) {
			str = scanner.next();
			count[Integer.parseInt(str)]++;
		}
		scanner.close();
		for (int i = 0; i < count.length; i++) {
			System.out.println("第" + (i + 1) + "组共有节点：" + count[i] + "个");
		}
	}

	public static void RMATProcess(String srcPath, String tarPath) throws IOException {
		FileReader fr = new FileReader(new File(srcPath));
		PrintWriter pw = new PrintWriter(tarPath);
		BufferedReader br = new BufferedReader(fr, 100 * 1024 * 1024);
		String str = null;
		for(int i = 0; i < 8; i++)
			br.readLine();
		while((str = br.readLine()) != null) {
			String[] splits = str.split(" ");
			pw.println(splits[splits.length - 3] + SEPARATOR + splits[splits.length - 2]);
		}
		br.close();
		pw.close();
	}

	public static void main(String[] args) throws IOException,
			InterruptedException, ClassNotFoundException {
		// GraphUtility.Count(args[0]);
		RMATProcess(args[0], args[1]);
	}
}
